/*
*********************
**data_structure.js**
*********************

- DataSet          单个数据组结构
- DataSetList      数据组列表
- WebInfo          项目本身结构
*/

/*

*/
class GlobalValue{
    /*
        公共数据
        1. 存储公共数据
        2. 数据之间的转换方法
    */

    // 数据获取的方式
    static DATA_METHOD_STRUCTURE = 100;
    static DATA_METHOD_CONTINUE = 101;
    static DATA_METHOD_SIMPLE_LIST = 102;

    // 数据刷新方式
    static DATA_REFRESH_SINGLE_PAGE = 110;
    static DATA_REFRESH_TURN_PAGE = 111;
    static DATA_REFRESH_WATERFALL = 112;
    static DATA_REFRESH_WATERFALL_BTN = 113;

    

    // 消息类型
    static MSG_TODO_GET_DATA_BINIDNG_XPATH = "getDataBindingXpath";

    // xpath 类型
    static XPATH_TYPE_SIMPLIST_TURN_PAGE_BUTTON = 120;           // 获取翻页按钮的xpath
    static XPATH_TYPE_SIMPLIST_GET_DATA_BINDING = 121;
    static XPATH_TYPE_SIMPLIST_WATERFALL_BUTTON = 122;

    static XPATH_TYPE_STRUCTURE_GET_DATA_BINDING = 125;
    static XPATH_TYPE_CONTINUES_GET_DATA = 126;


    /*
        元素的id名

        变量命名规则:
        "id_元素类型(小写)名称(首单词大写的驼峰)"

        值:
        "#" + 元素于html中的id名
        便于jq获取
        
        元素类型(包括不限于标签名, 主要类名):
        div
        container
        a
        p
    */

    // == basic
    static id_containerBasicInfo = "#container_basic_info";
    static id_valueProjectName = "#project_name";
    static id_valueProjectIntroduction = "#project_intro";
    static id_valueBackendAddress = "#backend_address";
    static id_valueAcquisitionMethod = "#data_acquisition_method";


    // == get data
    static id_containerGetData = "#container_get_data";
    static id_containerGetDataSimpleList = "#container_get_data_simple_list";
    static id_containerGetDataContinues = "#container_get_data_continues";
    static id_containerGetDataStructure = "#container_get_data_structure";

    // == get data - simple_list
    static id_containerDatabinding = "#container_data_binding";
    static id_valueSimpleListDataRefreshType = "#simple_list_data_refresh_type"
    static id_containerSimpleListSinglePage = "#container_data_refresh_single_page";
    static id_containerSimpleListTurnPage = "#container_data_refresh_turn_page";
    static id_containerSimpleListWaterfall = "#container_data_refresh_waterfall";
    static id_btnSimpleListTurnPage = "#btnGetTurnPageButton";
    static id_txtTurnPageButtonXpath = "#txtTurnPageButtonXpath";
    static id_txtSimpleListTurnPageTimes = "#txtTurnPageTimes";
    static id_txtWaterfallTimes = "#txtWaterFallTimes";

    static id_containerSimpleListWaterfallBtn = "#container_data_refresh_waterfall_with_button"
    static id_btnWaterFallButton = "#btnGetWaterFallButton";
    static id_txtWaterFallButtonXpath = "#txtWaterFallBtnXpath";
    static id_txtWaterFallTimesBtn = "#txtWaterFallTimesBtn";
    
    // == Warning Confirm Bar
    static id_containerWarningConfirm = "#container_warning_confirm";
    static id_divWarningContent = "#warning_content";
    static id_divWarningDivision = "#division_for_div_warning";
    static id_divWarningCollapse = "#div_warning_collapse";

    static id_containerSubmitConfirm = "#container_submit_confirm";
    static id_containerDeleteConfirm = "#container_delete_confirm";

    

}

/*
=================s
单个数据组结构
=================
*/
class DataSet {

    // 构造函数
    constructor(){
        this.name = "数据组名称";               // 数据组名称
        this.target_xpath = null;             // 目标数据xpath
        this.is_preview = false;              // 是否开启的预览
        this.scroll_top = 0;                   // 浏览器滑动的位置
    }

    // 激活预览
    active_preview(){
        this.is_preview = true;
        return true;
    }

    // 取消激活预览
    deactive_preview(){
        this.is_preview = false;
        return true;
    }
};


/*
=================
数据组列表
=================
*/
class DataSetList{
    constructor(){
        this.list_space = new Array();
        this.list_length = 0;
        this.list_size = 20;
    }

    // 初始化列表
    init_list(){
        this.list_space = [];
        this.list_length = 0;
    }

    // 清空列表
    clear_list(){
        for (let index = 0; index < this.list_length; index++) {
            this.list_space.shift();
        }
        this.init_list();
    }

    // 删除列表
    destory_list(){
        for (let index = 0; index < this.list_length; index++) {
            this.list_space.shift();
        }
        this.init_list();
    }

    // 新增一个数据组到列表
    insert_element(data_set){
        if (this.list_length >= this.list_size){
            return false;
        }

        this.list_space.push(data_set);
        this.list_length += 1;
        return true;
    }

    // 删除第i个数据组
    delete_element(i){
        // 验证输入
        if (i < 1 || i > this.list_length){
            return false;
        }

        // 删除元素
        this.list_space.splice(i-1, 1);
        this.list_length--
        return true;
    }

    // 获取第i个数据组
    get_element(i){
        // 验证输入
        if (i < 1 || i > this.list_length){
            return false;
        }

        return this.list_space[i-1];
    }

    // 获取第i个数据组的前驱
    get_front_element(i){
        // 验证输入
        if (i <= 1 || i > this.list_length){
            return false;
        }

        return this.list_space[i-1];
    }

    // 获取第i个数据组的后继
    get_behind_element(i){
        // 验证输入
        if (i < 1 || i >= this.list_length){
            return false;
        }

        return this.list_space[i+1];
    }
}

/*
=================
数据组
=================
*/
class DatasetObj{

    /*
        数据组要和数据标定（DataBinding）联合使用
    */

    constructor(obj_DataBinding){
		// 消息相关
        this.m_normal_obj = {
            tabId: chrome.devtools.inspectedWindow.tabId,
            msg_type: MSG_NORMAL,
        }

        // 数据组列表
        this.data_set_list = new DataSetList();                         

        // 数据组的按钮是否有激活 Jquery
        this.current_active_data_set_btn = null;

        // 状态量
        // 当前激活的data set(INT - 下标) -1: 没有数据组
        this.current_active_data_set = null;

        this.obj_DataBinding = obj_DataBinding;
        this.obj_WarningConfirm = new WarningConfirmBar();
        this.obj_SubmitConfirm = new SubmitConfirmBar();
    }
    
    // 注册删除数据组按钮
    register_delete_confirm(){
        this.hide_delete_confirm();
    }

    display_delete_confirm(){
        $(GlobalValue.id_containerDeleteConfirm).removeClass("d-none");
    }

    hide_delete_confirm(){
        $(GlobalValue.id_containerDeleteConfirm).addClass("d-none");
    }

    // 注册
    register(){
        /*
        动态添加的按钮, 在动态添加之后再绑定数据, 具体位置: bind_btn_operation_bar()
        */

        let obj_DataBinding = this.obj_DataBinding;
        let obj_DataSet = this;
        let obj_WarningConfirm = this.obj_WarningConfirm
        let obj_SubmitConfirm = this.obj_SubmitConfirm;

        this.register_delete_confirm();

        let mc_this = this;

        // 指定目标数据位置
        $('#btnGetValue').click(function(){
            /*
                1. 检查数据标定是否完成
                2. 改变html表现
                3. 发送消息
            */
            console.log("==获取数据组xpath==");

            if (obj_DataBinding.is_data_binding_done() === false){
                obj_WarningConfirm.display_warning("数据标定未完成");
                return false;
            }
            if ($('#btnGetValue').attr("value") === "clicked"){
                $('#btnGetValue').attr("value", "");
                $("#imgGetValue").attr("src", "click.svg");
            }else{
                $('#btnGetValue').attr("value", "clicked");
                $("#imgGetValue").attr("src", "clicked.svg");
            }

            /*
                2. 改变html表现
            */
            // 数据标定是否有激活的按钮
            
            if (obj_DataBinding.current_active_data_binding_btn !== null){
                // 有激活的按钮, 取消其激活状态
                obj_DataBinding.current_active_data_binding_btn.find("img").attr("value", "");
                obj_DataBinding.current_active_data_binding_btn.find("img").attr("src", "click.svg");
                obj_DataBinding.current_active_data_binding_btn = null;
            }

            // 数据组是否有激活按钮
            if (obj_DataSet.current_active_data_set_btn === null || obj_DataSet.current_active_data_set_btn === undefined){
                // 没有激活的按钮
                obj_DataSet.current_active_data_set_btn = $(this);
                $(this).find("img").attr("value", "clicked");
                $(this).find("img").attr("src", "clicked.svg");
            }else{
                // 有激活的按钮
                if (obj_DataSet.current_active_data_set_btn.is($(this))){
                    // 激活的是自己
                    // 取消激活
                    obj_DataSet.current_active_data_set_btn = null;
                    $(this).find("img").attr("value", "click");
                    $(this).find("img").attr("src", "click.svg");
                }else{
                    // 激活的是其他按钮
                    // 取消他们的激活
                    // 激活自己
                    obj_DataSet.current_active_data_set_btn = $(this);
                    $(this).find("img").attr("value", "clicked");
                    $(this).find("img").attr("src", "clicked.svg");
                }
            }

            /*
                3. 发送消息
                要求: 鼠标指定的数据必须要在数据标定的子结构里面, 返回时,检查是否有开启预览,如果有,发送预览请求
            */
            let msg = {
                msg_type: MSG_NORMAL,
                tabId: chrome.devtools.inspectedWindow.tabId,
                todo: "getTargetValue",
                xpath: obj_DataBinding.xpath_binding,
            }

            // == 不应该裸露原生的异步接口(造成大量的硬编码, 全局对象应该提供统一接口)
            web_info_object.send_msg_to_background(msg)
            // cbf_msg_send_to_background(msg);
        });

        $("#btnGetValue").mouseover(function(){
            if (obj_DataSet.current_active_data_set_btn === null || obj_DataSet.current_active_data_set_btn === undefined){
                $(this).find("img").attr("src", "clicked.svg");
            }else if($(this).attr("value") !== "clicked" && (obj_DataSet.current_active_data_set_btn.is($(this)) === false)){
                $(this).find("img").attr("src", "clicked.svg");
            }
        });

        $("#btnGetValue").mouseout(function(){
            if(obj_DataSet.current_active_data_set_btn === null || obj_DataSet.current_active_data_set_btn === undefined){
                $(this).find("img").attr("src", "click.svg");
            }else if ($(this).attr("value") !== "clicked" && (obj_DataSet.current_active_data_set_btn.is($(this)) === false)){
                $(this).find("img").attr("src", "click.svg");
            }
        });

        // 发送所有数据到服务器
        $('#btnSubmit').click(function(){
            /*
                发送项目信息到后台, 所发送的信息包括：
                - 项目的基本信息
                    * 项目名称
                    * 项目简介
                    * 服务器地址
                    * cookie
                    * 目标网站地址
                    * 数据获取方式
                - 获取数据页面的信息
                    + 数据标定
                        * 最小结构xpath
                        * 最大范围xpath
                        * 生成的子结构xpath列表
                    + 所有目标数据， 每组包括
                        * 数据组名称
                        * xpath
                        * 浏览器滑动的位置
            */
            console.log("==submit all data==");
            let submit_obj = web_info_object.return_submit_obj();
            if (submit_obj === false){
                // web_info_object.display_warning("数据标定未完成");
                obj_WarningConfirm.display_warning("数据标定未完成");
                return false;
            }
            console.log(submit_obj);

            // web_info_object.display_submit_confirm();
            obj_SubmitConfirm.display_submit_confirm();

            $.get("http://127.0.0.1:8000/ProjectManagement/api/sendBasicInfo/", submit_obj, function(data, status){
                    console.log('status:' + status);
                    console.log('data_status:' + data['status']);
                    console.log('task_id:' + data['task_id']);
                }
            )
        });

        // 监听数据组名称的改变
        $("#txtDataSetName").change(function(){
            // 获取当前激活的数据组
            // let i_current_data_set = web_info_object.current_active_data_set;
            let i_current_data_set = obj_DataSet.current_active_data_set;


            // 更改web info object的数据
            // web_info_object.data_set_list.list_space[i_current_data_set].name = $(this).val();
            obj_DataSet.data_set_list.list_space[i_current_data_set].name = $(this).val();
            

            // 更换操作栏的内容
            $("[name='btn_data_set'][index='" + i_current_data_set + "']").text($(this).val());
        });

        // 添加新的数据组
        $("#btn_add_new_data_set").click(function(){
            console.log("btn_add_new_data_set: == 添加新的数据组 ==");

            // 向数据存储添加一个新数据
            let new_data_set = new DataSet();
            // web_info_object.data_set_list.insert_element(new_data_set);
            obj_DataSet.data_set_list.insert_element(new_data_set);

            // 获取新添加数据组的id
            // let new_active_data_set_id = web_info_object.data_set_list.list_length - 1;
            let new_active_data_set_id = obj_DataSet.data_set_list.list_length - 1;
            

            // 重新设置激活数据组
            // web_info_object.current_active_data_set = new_active_data_set_id;
            obj_DataSet.current_active_data_set = new_active_data_set_id;

            // 刷新操作栏
            obj_DataSet.load_operation_bar();

            // 刷新数据
            obj_DataSet.load_data();
        });

        // 删除数据组
        $("#btn_delete_confirm_ok").click(function(){
            // 获取当前激活的数据组id
            let i_current_active_data_set = obj_DataSet.current_active_data_set;

            // 设置删除后的激活数据组
            let i_next_active = obj_DataSet.data_set_list.get_behind_element(i_current_active_data_set + 1);
            if (i_next_active === false){
                i_next_active = obj_DataSet.data_set_list.get_front_element(i_current_active_data_set + 1);
                if (i_next_active === false){
                    i_next_active = -1;
                }else{
                    i_next_active = i_current_active_data_set - 1;
                }
            }else{
                i_next_active = i_current_active_data_set;
            }

            // 判断该数据组是否激活了预览
            if (obj_DataSet.data_set_list.list_space[i_current_active_data_set].is_preview === true){
                obj_DataSet.m_deactive_preview(obj_DataSet.data_set_list, i_current_active_data_set);
            }

            // 从数据结构中删除数据组
            obj_DataSet.data_set_list.delete_element(i_current_active_data_set + 1);

            // 设置激活的数据组
            obj_DataSet.current_active_data_set = i_next_active;

            // 刷新操作栏
            obj_DataSet.load_operation_bar();

            // 刷新数据
            obj_DataSet.load_data();

            // 隐藏确认框
            // hide_delete_confirm();
            // obj_WarningConfirm.hide_warning();
            obj_DataSet.hide_delete_confirm();
        });

        // 取消删除数据组
        $("#btn_delete_confirm_cancel").click(function(){
            // 隐藏确认框
            // hide_delete_confirm();
            // obj_WarningConfirm.hide_warning();
            obj_DataSet.hide_delete_confirm();
        });
    }

    // 显示
    active(){
        // 加载操作栏
        this.load_operation_bar();

        // 加载具体数据
        this.load_data();
    }

    // 加载操作栏
    load_operation_bar(){

        let obj_DataSet = this;

        let ul_data_set_container = $("#ul_data_set");
        // 初始化数据组html元素
        ul_data_set_container.empty();

        // 获取缓存信息
        let data_set_num = obj_DataSet.data_set_list.list_length;

        /*
        根据获取的信息动态加载数据组
        - 所有button初始加载为未激活
        - 所有button的id最后都添加index的序号如'btn_delete_0'
        - 所有button都带有属性index表示下标
        - 动态生成的所有btn的name都相同: btn_data_set_preview, btn_delete, btn_data_set
        - 每4个按钮为一组,包含在一个div里面, 每个div带有属性 index表示下表
        */

        // 获取"div组"
        let i_div_num = parseInt(data_set_num / 4);
        if (data_set_num % 4 != 0){
            i_div_num += 1;
        }
        // console.log("data set num:" + data_set_num);
        // console.log("div num:" + i_div_num);


        let el_div_li_container_list = new Array();
        for (let index = 0; index < i_div_num; index++) {
            let el_div_li_container = $("<div index = '" + index + "' class='navbar-nav' style='width: 100%;  margin: 5px'></div>");
            el_div_li_container_list.push(el_div_li_container);
        }
        // console.log("el_div_li_container_list length:" + el_div_li_container_list.length);


        // 设置数据
        for (let index = 0; index < data_set_num; index++) {
            // console.log("load_operation_bar: loop - " + index);
            let data_set = obj_DataSet.data_set_list.get_element(index+1);

            let el_li = $("<li class='nav-item  mw_date_set_card col-md-3 col-lg-3'></li>");
            let el_div_row = $("<div class='row'></div>");
            let el_div_col = $("<div class='col-md-12 col-sm-12'></div>");
            let el_div_data_set_container = $("<div class='justify-content-center text-wrap'></div>");
            // let el_div_data_set_container = $("<div class='d-flex justify-content-center text-wrap'></div>");
            let el_btn_data_set = $("<button index = '" + index + "' name='btn_data_set' class='btn btn-block btn-data-set-name' id='btn_data_set_" + index + "'>" + data_set.name +"</button>");
            let el_div_division = $("<div class='mw_division_10'></div>");
            let el_div_operation_container = $("<div class='d-flex justify-content-center flex-row'></div>");
            let el_div_preview = $("<div class='col-md-6 col-sm-6 col-lg-6 d-flex pl-0'></div>");

            let el_btn_preview = null;
            if (data_set.is_preview === true){
                el_btn_preview = $("<button value='clicked' index = '" + index + "' name='btn_data_set_preview' class='btn btn-preview-data btn-block' id='btn_preview_" + index + "'>预览</button>")
                el_btn_preview.css("background-color", "#f07b3f");
                el_btn_preview.css("color", "#ffffff");
            }else if (data_set.is_preview === false){
                el_btn_preview = $("<button index = '" + index + "' name='btn_data_set_preview' class='btn btn-preview-data btn-block' id='btn_preview_" + index + "'>预览</button>")
            }
            
            let el_div_delete = $("<div class='col-md-6 col-sm-6 col-lg-6 d-flex pr-0'></div>");
            let el_btn_delete = $("<button index = '" + index + "' name='btn_delete' class='btn btn-outline-danger btn-delete-data btn-block' id='btn_delete_" + index + "'>删除</button>");
            
            el_li.append(el_div_row);
            el_div_row.append(el_div_col);

            el_div_col.append(el_div_data_set_container);
            el_div_col.append(el_div_division);
            el_div_col.append(el_div_operation_container);

            el_div_data_set_container.append(el_btn_data_set);
            
            el_div_operation_container.append(el_div_preview);
            el_div_operation_container.append(el_div_delete);

            el_div_preview.append(el_btn_preview);
            el_div_delete.append(el_btn_delete);

            // 这个数据组属于哪一个div(下标)
            let i_div_index = parseInt(index/4);
            // console.log("i_div_index:" + i_div_index);

            // 添加数据组到div
            el_div_li_container_list[i_div_index].append(el_li);      
            // console.log("addend");
        }

        // 将所有div添加到ul
        for (let index = 0; index < el_div_li_container_list.length; index++) {
            ul_data_set_container.append(el_div_li_container_list[index]);
        }

        // == 设置元素的表现
        // 设置当前激活的项目
        let i_current_active_data_set = obj_DataSet.current_active_data_set;
        this.set_active_data_set_btn(i_current_active_data_set);

        // 设置预览按钮状态

        // 绑定操作栏元素的表现和响应
        this.bind_btn_operation_bar();
    }

    // 加载具体数据
    load_data(){

        let obj_DataSet = this;

        // 获取当前激活的数据组
        let data_set_index = obj_DataSet.current_active_data_set;

        if (data_set_index !== -1){
            // 设置数据
            let obj_current_active_data_set = obj_DataSet.data_set_list.get_element(data_set_index+1);
            $("#txtDataSetName").val(obj_current_active_data_set.name);
            $("#xpath").val(obj_current_active_data_set.target_xpath);
            $("#maxRangeXpath").val(obj_current_active_data_set.max_range_xpath);
            $("#sub_range_xpath").val(obj_current_active_data_set.sub_range_xpath);
        }else{
            // 没有数据组
            // 隐藏数据显示模块
            $("#div_get_data").css("display", "");
        }
    }

    // 绑定操作栏的元素表现
    // 如果不这样做,Jquery动态添加的元素得不到正确的响应
    bind_btn_operation_bar(){

        let obj_DataSet = this;

        // Preview 按钮
        $("button.btn-preview-data").mouseover(function(){
            if ($(this).attr("value") !== "clicked"){
                $(this).css("background-color", "#f07b3f");
                $(this).css("color", "#ffffff");
            } 
        });

        $("button.btn-preview-data").mouseout(function(){
            if ($(this).attr("value") !== "clicked"){
                $(this).css("background-color", "#ffffff");
                $(this).css("color", "#f07b3f");
            }
        });

        // 预览按钮
        // $("button.btn-preview-data")
        $("[name='btn_data_set_preview']").click(function(){
            let index = Number($(this).attr("index"));

            // 改变表现
            if ($(this).attr("value") === "clicked"){
                // 取消激活预览按钮
                $(this).attr("value", "");
                $(this).css("background-color", "#ffffff");
                $(this).css("color", "#f07b3f");
                // 发送消息
                obj_DataSet.m_deactive_preview(obj_DataSet.data_set_list, index);

                // 取消激活状态
                obj_DataSet.data_set_list.list_space[index].deactive_preview();
            }else{
                $(this).attr("value", "clicked");
                $(this).css("background-color", "#f07b3f");
                $(this).css("color", "#ffffff");
                // 发送消息
                obj_DataSet.m_active_preview(obj_DataSet.data_set_list, index);

                // 设置激活状态
                obj_DataSet.data_set_list.list_space[index].active_preview();
            }
        });

        // Delete 按钮
        $("[name='btn_delete']").click(function(){
            
            // 设置当前激活的数据组
            let index = Number($(this).attr("index"));
            obj_DataSet.current_active_data_set = index;

            // 激活按钮
            obj_DataSet.set_active_data_set_btn(index);

            // 更换数据
            obj_DataSet.load_data();

            // 显示确认框
            // this.display_delete_confirm();
            // mc_GetData.delete_confirm.display_delete_confirm();
            // mc_this.display_delete_confirm();
            obj_DataSet.display_delete_confirm();

            // 设置确认框的数据组名称
            $("#span_delete_confirm_data_set_name").text(obj_DataSet.data_set_list.get_element(index+1).name);
        });

        // DataSet 按钮
        $("[name='btn_data_set']").click(function(){
            console.log("btn data set click");
            // 设置当前激活的数据组
            let index = Number($(this).attr("index"));
            obj_DataSet.current_active_data_set = index;

            // 激活按钮
            // mc_GetData.simple_list.set_active_data_set_btn(index);
            obj_DataSet.set_active_data_set_btn(index);

            // 更换数据
            // mc_GetData.simple_list.load_data(index);
            obj_DataSet.load_data(index);
        });


    }

    // 设置激活的数据组按钮
    set_active_data_set_btn(index){
        // 初始化所有的按钮
        let data_set_num = this.data_set_list.list_length;
        for (let i = 0; i < data_set_num; i++) {
            let btn_id = "btn_data_set_" + i;
            $("#" + btn_id).css("background-color", "#fecea8");
        }

        // 设置激活的按钮
        let target_data_set_id = "btn_data_set_" + index;
        $("#" + target_data_set_id).css('background-color', "#e84a5f");
    }

	
	/*
		判断给定的index(下标)数据组是否激活了预览
		param list: 		列表 - DataSetList
		param index: 		数据组下标
	*/
	is_data_set_preview(list, index){
		if (index >= list.list_length){
			return false;
		}

		if (list.list_space[index].is_preview === true){
			return true;
		}else{
			return false;
		}
    }
    
    /*
        DataSet list 转换为obj
        param list: DataSetList
    */

    data_set_list_to_obj(list){
        let return_obj = new Object();
        for (let i = 0; i < list.list_length; i++) {
            const element = list.list_space[i];
            let element_obj = new Object();
            element_obj.name = element.name;
            element_obj.target_xpath = element.target_xpath;
            element_obj.scroll_top = element.scroll_top;
            return_obj["data_set_" + i] = element_obj;
        }
        return return_obj;
    }

    /*
        取消所有的激活
    */
    deactive_all_preview(){
        let list_length = this.data_set_list.list_length;
        for (let i = 0; i < list_length; i++) {
            const data_set = this.data_set_list.list_space[i];
            if (data_set.is_preview === true){
                // 取消激活预览按钮
                let btn_data_set = $("btn_data_set_" + i);
                btn_data_set.attr("value", "");
                btn_data_set.css("background-color", "#ffffff");
                btn_data_set.css("color", "#f07b3f");
                // 发送消息
                this.m_deactive_preview(this.data_set_list, i);

                // 取消激活状态
                this.data_set_list.list_space[i].deactive_preview();
            }
        }
    }


    /*
    ===============
    消息传输 to content.js
    "m_" - 消息传输函数
    ===============
    */

	/*
		激活数据组的预览
		param list:		列表 - DataSetList
		param index: 	要激活的数据组的下标
	*/
	m_active_preview(list, index){
		console.log("==active data set data preview==");
		// 验证数据组是否激活
		if (this.is_data_set_preview(list, index) === false){
			// 发送消息
			let msg = this.m_normal_obj;
			msg.todo = "activeDataSetPreview";
			msg.index = index;
			msg.xpath = list.list_space[index].target_xpath;
			cbf_msg_send_to_background(msg);
		}else{
			console.log("faile, invalid index or data set is not active");
		}
	}

	/*
		取消激活数据组的预览
		param list: DataSetList
		
	*/
	m_deactive_preview(list, index){
		console.log("==deactive data set data preview==");
		if (this.is_data_set_preview(list, index) === true){
			// 发送消息
			let msg = this.m_normal_obj;
			msg.todo = "deactiveDataSetPreview";
			msg.index = index;
			cbf_msg_send_to_background(msg);
		}else{
			console.log("faile, invalid index or data set is not active");
		}
	}
}

/*
=================
数据标定
=================
*/
class DataBinding{
    // 检测xpath是否在锁定的max里面的询问者
    static ASKER_DATA_BINDING_XPATH = 100;
    static ASKER_DATA_BINDING_XPATH_UP = 101;
    static ASKER_DATA_BINDING_XPATH_DOWN = 102;

    static is_registered = false;


    constructor(){
        this.xpath_binding = null;                      // 指定标定数据位置xpath
        this.max_xpath_binding = null;                  // 最大范围xpath
        this.sub_xpath_binding_list = new Array();      // 子结构xpath
        this.is_preview = false;                        // 是否激活了预览
        this.is_lock_max_xpath = false;                 // 是否锁定了最大范围

        this.data_refresh_type = GlobalValue.DATA_REFRESH_SINGLE_PAGE;                  // 数据刷新方式
        this.turn_page_xpath = null;
        this.turn_page_times = 0;
        this.turn_page_scrolltop = 0;

        this.waterfall_times = 0;

        this.waterfall_btn_xpath = null;
        this.waterfall_btn_scrolltop = 0;
        this.waterfall_btn_times = 0;

        this.color_data_binding_background = {
            "r": 255,
            "g": 82,
            "b": 33
        };

        this.color_data_binding_border = {
            "r": 151,
            "g": 49,
            "b": 20
        };

        this.color_max_background = {
            "r": 58,
            "g": 205,
            "b": 255
        };

        this.color_max_border = {
            "r": 27,
            "g": 97,
            "b": 121
        };

        this.color_sub_background = {
            "r": 255,
            "g": 92,
            "b": 170
        };

        this.color_sub_border = {
            "r": 131,
            "g": 47,
            "b": 87
        };

        /*
            变量说明 - xpath_binding_ori
            在鼠标获取binding xpath的时候，会将得到的xpath同时赋值给 xpath_binding 以及 xpath_binding_ori
            xpath_binding_ori相当于一个备份，且只有在“鼠标获取binding xpath”的时候才会发生改变

            该变量用于调整xpath_binging的范围，其角色相当于调整的一个参考
        */
        this.xpath_binding_ori = null;

        // 消息相关
        this.m_normal_obj = {
            tabId: chrome.devtools.inspectedWindow.tabId,
            msg_type: MSG_NORMAL,
        }

        // 状态量
        // 当前激活的数据绑定按钮
        this.current_active_data_binding_btn = null;

        this.obj_DataBinding = this;
    }


    // 注册data binding
    register(){

        if (DataBinding.is_registered === false){

            DataBinding.is_registered = true;

            let obj_DataBinding = this.obj_DataBinding;

            let obj_WarningConfirm = new WarningConfirmBar();        

            /*
            =================
            数据标定的按钮事件监听
            =================
            */

            // this.register_btnBindValue();
            // 指定标定数据位置
            $("#btnBindValue").click(function(event){
                let tmp_obj_DataBinding = obj_DataBinding.get_current_data_binding_obj();
                console.log($('#btnGetValue').attr("value"));        
            
                // 改变元素显示
                if (tmp_obj_DataBinding.current_active_data_binding_btn === null || tmp_obj_DataBinding.current_active_data_binding_btn === undefined){
                    // 当前无占用
                    // 激活按钮
                    tmp_obj_DataBinding.current_active_data_binding_btn = $(this);
                    tmp_obj_DataBinding.current_active_data_binding_btn.find("img").attr("value", "clicked");
                    tmp_obj_DataBinding.current_active_data_binding_btn.find("img").attr("src", "clicked.svg");
                }else if(tmp_obj_DataBinding.current_active_data_binding_btn.is($(this))){
                    // 自己占用
                    // 取消激活状态
                    tmp_obj_DataBinding.current_active_data_binding_btn.find("img").attr("value", "");
                    tmp_obj_DataBinding.current_active_data_binding_btn.find("img").attr("src", "click.svg");
                    tmp_obj_DataBinding.current_active_data_binding_btn = null;
                }else{
                    // 其他按钮占用
                    // 取消其他按钮激活状态
                    // 激活本按钮
                    tmp_obj_DataBinding.current_active_data_binding_btn.find("img").attr("value", "");
                    tmp_obj_DataBinding.current_active_data_binding_btn.find("img").attr("src", "click.svg");
                    tmp_obj_DataBinding.current_active_data_binding_btn = $(this);
                    tmp_obj_DataBinding.current_active_data_binding_btn.find("img").attr("value", "clicked");
                    tmp_obj_DataBinding.current_active_data_binding_btn.find("img").attr("src", "clicked.svg");
                }
            
                // 发送数据
                // 检查最大方位是否有锁定
                if (tmp_obj_DataBinding.is_lock_max_xpath === true){
                    tmp_obj_DataBinding.m_get_data_binding(GlobalValue.XPATH_TYPE_SIMPLIST_GET_DATA_BINDING, is_lock_max=1, lock_max=tmp_obj_DataBinding.max_xpath_binding);
                }else{
                    tmp_obj_DataBinding.m_get_data_binding(GlobalValue.XPATH_TYPE_SIMPLIST_GET_DATA_BINDING);
                }
            });

            // 指定最大范围
            $('#btnBindMaxXpath').click(function(){
                let tmp_obj_DataBinding = obj_DataBinding.get_current_data_binding_obj();
                // 改变元素表现
                if (tmp_obj_DataBinding.current_active_data_binding_btn === null || tmp_obj_DataBinding.current_active_data_binding_btn === undefined){
                    // 当前无占用
                    // 激活按钮
                    tmp_obj_DataBinding.current_active_data_binding_btn = $(this);
                    tmp_obj_DataBinding.current_active_data_binding_btn.find("img").attr("value", "clicked");
                    tmp_obj_DataBinding.current_active_data_binding_btn.find("img").attr("src", "clicked.svg");
                }else if(tmp_obj_DataBinding.current_active_data_binding_btn.is($(this))){
                    // 自己占用
                    // 取消激活状态
                    tmp_obj_DataBinding.current_active_data_binding_btn.find("img").attr("value", "");
                    tmp_obj_DataBinding.current_active_data_binding_btn.find("img").attr("src", "click.svg");
                    tmp_obj_DataBinding.current_active_data_binding_btn = null;
                }else{
                    // 其他按钮占用
                    // 取消其他按钮激活状态
                    // 激活本按钮
                    tmp_obj_DataBinding.current_active_data_binding_btn.find("img").attr("value", "");
                    tmp_obj_DataBinding.current_active_data_binding_btn.find("img").attr("src", "click.svg");
                    tmp_obj_DataBinding.current_active_data_binding_btn = $(this);
                    tmp_obj_DataBinding.current_active_data_binding_btn.find("img").attr("value", "clicked");
                    tmp_obj_DataBinding.current_active_data_binding_btn.find("img").attr("src", "clicked.svg");
                }
                let s_xpath = $("#xpathBinding").val();
                tmp_obj_DataBinding.m_get_max_range_xpath(s_xpath);
            });

            // 自动生成子结构
            $("#a_auto_create_sub_range_xpath").click(function(){
                console.log("==自动生成子结构==");

                // 获取xpath和最大xpath
                let s_xpath = $("#xpathBinding").val();
                let s_max_range_xpath = $("#maxXpathBinding").val();

                if(s_xpath === "" || s_max_range_xpath === ""){
                    // 缺少数值
                    console.log("缺少数值");
                    return false;
                }

                let msg = {
                    tabId: chrome.devtools.inspectedWindow.tabId,
                    todo: "autoSubRange",
                    xpath: s_xpath,
                    max_range_xpath: s_max_range_xpath,
                }

                // auto_sub_range(msg);
                // cbf_msg_send_to_background(msg);
                web_info_object.send_msg_to_background(msg);

            });

            // 调整绑定数据的范围
            $("#adjust_binding_xpath_up").click(function(){
                let tmp_obj_DataBinding = obj_DataBinding.get_current_data_binding_obj();
                // 检查数据绑定是否完成
                if (tmp_obj_DataBinding.is_data_binding_done() === false){
                    console.log("==BTN: adjust_binding_xpath_up==");
                    console.log("Error: data binding is not done");
                    // web_info_object.display_warning("未完成数据绑定");
                    obj_WarningConfirm.display_warning("未完成数据绑定");
                    return false;
                }

                // 发送消息到content.js
                // 检查是否锁定了最大范围
                if (tmp_obj_DataBinding.is_lock_max_xpath === true){
                    let s_xpath = $("#xpathBinding").val();
                    let s_max_range_xpath = $("#maxXpathBinding").val();
                    tmp_obj_DataBinding.m_adjust_binding_xpath_up(s_xpath, s_max_range_xpath, is_lock_max=1);
                }else{
                    let s_xpath = $("#xpathBinding").val();
                    let s_max_range_xpath = $("#maxXpathBinding").val();
                    tmp_obj_DataBinding.m_adjust_binding_xpath_up(s_xpath, s_max_range_xpath);
                }
            });

            $("#adjust_binding_xpath_down").click(function(){
                let tmp_obj_DataBinding = obj_DataBinding.get_current_data_binding_obj();
                // 检查数据绑定是否完成
                if (tmp_obj_DataBinding.is_data_binding_done() === false){
                    console.log("==BTN: adjust_binding_xpath_down==");
                    console.log("Error: data binding is not done");
                    // web_info_object.display_warning("未完成数据绑定");
                    obj_WarningConfirm.display_warning("未完成数据标定");
                    return false;
                }

                // 发送消息到content.js
                let s_xpath = $("#xpathBinding").val();
                let s_max_range_xpath = $("#maxXpathBinding").val();
                let s_xpath_ori = tmp_obj_DataBinding.xpath_binding_ori;
                tmp_obj_DataBinding.m_adjust_binding_xpath_down(s_xpath, s_xpath_ori, s_max_range_xpath);
            });

            // 调整最大范围
            $("#adjust_max_xpath_up").click(function(){
                let tmp_obj_DataBinding = obj_DataBinding.get_current_data_binding_obj();
                // 检查数据绑定是否完成
                if (tmp_obj_DataBinding.is_data_binding_done() === false){
                    console.log("==BTN: adjust_max_xpath_up==");
                    console.log("Error: data binding is not done");
                    obj_WarningConfirm.display_warning("未完成数据绑定");
                    return false;
                }

                // 发送调整消息到content.js
                let s_max_range_xpath = $("#maxXpathBinding").val();
                let s_xpath = $("#xpathBinding").val();
                tmp_obj_DataBinding.m_adjust_max_range_up(s_xpath, s_max_range_xpath);
            });

            $("#adjust_max_xpath_down").click(function(){
                let tmp_obj_DataBinding = obj_DataBinding.get_current_data_binding_obj();
                // 检查数据绑定是否完成
                if (tmp_obj_DataBinding.is_data_binding_done() === false){
                    console.log("==BTN: adjust_max_xpath_down==");
                    console.log("Error: data binding is not done");
                    obj_WarningConfirm.display_warning("未完成数据绑定");
                    return false;
                }

                // 发送调整消息到content.js
                let s_max_range_xpath = $("#maxXpathBinding").val();
                let s_xpath = $("#xpathBinding").val();
                tmp_obj_DataBinding.m_adjust_max_range_down(s_xpath, s_max_range_xpath);

            });

            // 锁定最大范围
            $("#adjust_max_xpath_lock").click(function(){
                let tmp_obj_DataBinding = obj_DataBinding.get_current_data_binding_obj();
                let data_binding_max = tmp_obj_DataBinding.max_xpath_binding;
                // 检查数据有效性
                if (data_binding_max === "" || data_binding_max === null || data_binding_max === undefined){
                    obj_WarningConfirm.display_warning("数据标定未完成");
                    return false;
                }

                // 改变html表现
                // 改变变量值
                if (tmp_obj_DataBinding.is_lock_max_xpath === true){
                    tmp_obj_DataBinding.is_lock_max_xpath = false;
                    $(this).text("lock");
                }else if (tmp_obj_DataBinding.is_lock_max_xpath === false){
                    tmp_obj_DataBinding.is_lock_max_xpath = true;
                    $(this).text("locked");
                }else{
                    console.log("==adjust_max_xpath_lock==");
                    console.log("error");
                    console.log("is lock valule:" + tmp_obj_DataBinding.is_lock_max_xpath);
                }
            });
            
            // 预览
            $("#btn_data_binding_preview").click(function(){

                let tmp_obj_DataBinding = obj_DataBinding.get_current_data_binding_obj();

                // 检查数据标定
                if (tmp_obj_DataBinding.is_data_binding_done() === false){
                    obj_WarningConfirm.display_warning("数据标定未完成");
                    // display_warning("数据标定未完成");
                    return false;
                }

                // 改变表现
                if ($(this).attr("value") === "clicked"){
                    // 取消激活预览按钮
                    $(this).attr("value", "");
                    $(this).css("background-color", "#ffffff");
                    $(this).css("color", "#f07b3f");
                    tmp_obj_DataBinding.deactive_preview();
                    tmp_obj_DataBinding.m_deactive_preview();
                }else{
                    // 激活预览按钮
                    $(this).attr("value", "clicked");
                    $(this).css("background-color", "#f07b3f");
                    $(this).css("color", "#ffffff");
                    tmp_obj_DataBinding.active_preview();
                    tmp_obj_DataBinding.m_active_preview();
                }            
            });

            $("button.btn-get-xpath").mouseover(function(){

                let tmp_obj_DataBinding = obj_DataBinding.get_current_data_binding_obj();

                if (tmp_obj_DataBinding.current_active_data_binding_btn === null || tmp_obj_DataBinding.current_active_data_binding_btn === undefined){
                    $(this).find("img").attr("src", "clicked.svg");
                }else if($(this).attr("value") !== "clicked" && (tmp_obj_DataBinding.current_active_data_binding_btn.is($(this)) === false)){
                    $(this).find("img").attr("src", "clicked.svg");
                }

            });

            $("button.btn-get-xpath").mouseout(function(){

                let tmp_obj_DataBinding = obj_DataBinding.get_current_data_binding_obj();

                if(tmp_obj_DataBinding.current_active_data_binding_btn === null || tmp_obj_DataBinding.current_active_data_binding_btn === undefined){
                    $(this).find("img").attr("src", "click.svg");
                }else if ($(this).attr("value") !== "clicked" && (tmp_obj_DataBinding.current_active_data_binding_btn.is($(this)) === false)){
                    $(this).find("img").attr("src", "click.svg");
                }
            });

            // 数据刷新
            $(GlobalValue.id_valueSimpleListDataRefreshType).change(function(){
                let tmp_obj_DataBinding = obj_DataBinding.get_current_data_binding_obj();
                if ($(this)[0].value === "single_page"){
                    tmp_obj_DataBinding.data_refresh_type = GlobalValue.DATA_REFRESH_SINGLE_PAGE;
                }else if($(this)[0].value === "turn_page"){
                    tmp_obj_DataBinding.data_refresh_type = GlobalValue.DATA_REFRESH_TURN_PAGE;
                }else if($(this)[0].value === "waterfall"){
                    tmp_obj_DataBinding.data_refresh_type = GlobalValue.DATA_REFRESH_WATERFALL;
                }else if($(this)[0].value === "waterfall_btn"){
                    tmp_obj_DataBinding.data_refresh_type = GlobalValue.DATA_REFRESH_WATERFALL_BTN;
                }

                tmp_obj_DataBinding.refresh_data_refresh_selection();
            });

            $(GlobalValue.id_btnSimpleListTurnPage).click(function(){
                let tmp_obj_DataBinding = obj_DataBinding.get_current_data_binding_obj();
                tmp_obj_DataBinding.m_get_data_binding(GlobalValue.XPATH_TYPE_SIMPLIST_TURN_PAGE_BUTTON);
            });

            $(GlobalValue.id_txtSimpleListTurnPageTimes).change(function(){
                let tmp_obj_DataBinding = obj_DataBinding.get_current_data_binding_obj();
                // 验证数据输入的合法性
                let value = $(this).val();
                if (isNaN(value)){
                    console.log("输入数据不合法");
                    obj_WarningConfirm.display_warning("输入数据不合法");
                    $(this).val(tmp_obj_DataBinding.turn_page_times);
                    return false;
                }else{
                    tmp_obj_DataBinding.turn_page_times = value;
                }
            });

            $(GlobalValue.id_txtWaterfallTimes).change(function(){
                let tmp_obj_DataBinding = obj_DataBinding.get_current_data_binding_obj();
                let value = $(this).val();
                if (isNaN(value)){
                    console.log("输入数据不合法");
                    obj_WarningConfirm.display_warning("输入数据不合法");
                    $(this).val(tmp_obj_DataBinding.waterfall_times);
                    return false;
                }else{
                    tmp_obj_DataBinding.waterfall_times = value;
                }
            });

            // 数据刷新 waterfall btn
            $(GlobalValue.id_btnWaterFallButton).click(function(){
                let tmp_obj_DataBinding = obj_DataBinding.get_current_data_binding_obj();
                tmp_obj_DataBinding.m_get_data_binding(GlobalValue.XPATH_TYPE_SIMPLIST_WATERFALL_BUTTON);
            });

            $(GlobalValue.id_txtWaterFallTimesBtn).change(function(){
                let tmp_obj_DataBinding = obj_DataBinding.get_current_data_binding_obj();
                let value = $(this).val();
                if (isNaN(value)){
                    console.log("输入数据不合法");
                    obj_WarningConfirm.display_warning("输入数据不合法");
                    $(this).val(tmp_obj_DataBinding.waterfall_btn_times);
                    return false;
                }else{
                    tmp_obj_DataBinding.waterfall_btn_times = value;
                }
            });

            /*
                setting
            */
            $("#color_data_binding_backgorund").change(function(){
                obj_DataBinding.color_data_binding_background = obj_DataBinding.showRGB2($(this).val());

                if (obj_DataBinding.is_preview === true){
                    obj_DataBinding.m_refresh_preview("data_binding_background", obj_DataBinding.color_data_binding_background);
                }
            });

            $("#color_data_binding_border").change(function(){
                obj_DataBinding.color_data_binding_border = obj_DataBinding.showRGB2($(this).val());

                if (obj_DataBinding.is_preview === true){
                    obj_DataBinding.m_refresh_preview("data_binding_border", obj_DataBinding.color_data_binding_border);
                }
            });

            $("#color_max_backgorund").change(function(){
                obj_DataBinding.color_max_background = obj_DataBinding.showRGB2($(this).val());

                if (obj_DataBinding.is_preview === true){
                    obj_DataBinding.m_refresh_preview("max_background", obj_DataBinding.color_max_background);
                }
            });

            $("#color_max_border").change(function(){
                obj_DataBinding.color_max_border = obj_DataBinding.showRGB2($(this).val());
                if (obj_DataBinding.is_preview === true){
                    obj_DataBinding.m_refresh_preview("max_border", obj_DataBinding.color_max_border);
                }
            });

            $("#color_sub_backgorund").change(function(){
                obj_DataBinding.color_sub_background = obj_DataBinding.showRGB2($(this).val());
                if (obj_DataBinding.is_preview === true){
                    obj_DataBinding.m_refresh_preview("sub_background", obj_DataBinding.color_sub_background);
                }
            });

            $("#color_sub_border").change(function(){
                obj_DataBinding.color_sub_border = obj_DataBinding.showRGB2($(this).val());
                if (obj_DataBinding.is_preview === true){
                    obj_DataBinding.m_refresh_preview("sub_border", obj_DataBinding.color_sub_border);
                }
            });


            /*
                setting status
            */
            $("#cbox_data_binding_background").click(function(){
                // 激活/取消激活
                if ($(this).prop("checked") === true){
                    obj_DataBinding.m_update_preview_info("data_binding_background", "activate");
                }else{
                    obj_DataBinding.m_update_preview_info("data_binding_background", "deactivate");
                }
            });


            $("#cbox_data_binding_border").click(function(){
                if ($(this).prop("checked") === true){
                    obj_DataBinding.m_update_preview_info("data_binding_border", "activate");
                }else{
                    obj_DataBinding.m_update_preview_info("data_binding_border", "deactivate");
                }
            });

            $("#cbox_max_background").click(function(){
                if ($(this).prop("checked") === true){
                    obj_DataBinding.m_update_preview_info("max_background", "activate");
                }else{
                    obj_DataBinding.m_update_preview_info("max_background", "deactivate");
                }
            });

            $("#cbox_max_bording").click(function(){
                if ($(this).prop("checked") === true){
                    obj_DataBinding.m_update_preview_info("max_border", "activate");
                }else{
                    obj_DataBinding.m_update_preview_info("max_border", "deactivate");
                }
            });

            $("#cbox_sub_background").click(function(){
                if ($(this).prop("checked") === true){
                    obj_DataBinding.m_update_preview_info("sub_background", "activate");
                }else{
                    obj_DataBinding.m_update_preview_info("sub_background", "deactivate");
                }
            });

            $("#cbox_sub_bording").click(function(){
                if ($(this).prop("checked") === true){
                    obj_DataBinding.m_update_preview_info("sub_border", "activate");
                }else{
                    obj_DataBinding.m_update_preview_info("sub_border", "deactivate");
                }
            });

        }
    }

    // 获取当前的实例
    get_current_data_binding_obj(){
        let tmp_obj_DataBinding = null;
        if (mc_BasicInfo.data_acquisition_method === GlobalValue.DATA_METHOD_STRUCTURE){
            tmp_obj_DataBinding = mc_GetData.structure.data_binding_set;
        }else if(mc_BasicInfo.data_acquisition_method === GlobalValue.DATA_METHOD_SIMPLE_LIST){
            tmp_obj_DataBinding = mc_GetData.simple_list.data_binding_set;
        }else{
            tmp_obj_DataBinding = mc_GetData.simple_list.data_binding_set;
        }

        return tmp_obj_DataBinding;
    }

    // 刷新“数据刷新方式”的html元素表现
    refresh_data_refresh_selection(){

        $(GlobalValue.id_containerSimpleListSinglePage).addClass("d-none");
        $(GlobalValue.id_containerSimpleListTurnPage).addClass("d-none");
        $(GlobalValue.id_containerSimpleListWaterfall).addClass("d-none");
        $(GlobalValue.id_containerSimpleListWaterfallBtn).addClass("d-none");


        let select_type = this.data_refresh_type;
        if (select_type === GlobalValue.DATA_REFRESH_SINGLE_PAGE){
            $(GlobalValue.id_containerSimpleListSinglePage).removeClass("d-none");
        }else if(select_type === GlobalValue.DATA_REFRESH_TURN_PAGE){
            $(GlobalValue.id_containerSimpleListTurnPage).removeClass("d-none");
        }else if(select_type === GlobalValue.DATA_REFRESH_WATERFALL){
            $(GlobalValue.id_containerSimpleListWaterfall).removeClass("d-none");
        }else if(select_type === GlobalValue.DATA_REFRESH_WATERFALL_BTN){
            $(GlobalValue.id_containerSimpleListWaterfallBtn).removeClass("d-none");
        }
    }

    // 显示元素
    active(){

    }

    // 初始化组件
    init_element(){

    }

    // 改变preview状态
    active_preview(){
        this.is_preview = true;
        return true;
    }

    // 改变preview状态
    deactive_preview(){
        this.is_preview = false;
        return true;
    }

    // 是否完成数据标定
    is_data_binding_done(){
        if (this.xpath_binding === null || this.xpath_binding === undefined || this.xpath_binding === ""){
            console.log("send_active_preivew: 数据标定未完成");
            return false;
        }else{
            return true;
        }
    }

    // 将sub_xpath_binding_list转换成obj
    sub_xpath_binding_list_to_obj(){
        let return_obj = new Object();
        for (let i = 0; i < this.sub_xpath_binding_list.length; i++) {
            const element = this.sub_xpath_binding_list[i];
            return_obj["sub_xpath_binding_" + i] = element;
        }
        return return_obj;
    }

    // 更新html页面组件
    update_html(){
        $("#xpathBinding").val(this.xpath_binding);
        $("#maxXpathBinding").val(this.max_xpath_binding);
        $("#span_sub_num").text(this.sub_xpath_binding_list.length);
    }

    // 重置databinding的html表现
    reset_data_binding_html(){
        $("#xpathBinding").val("");

    }

    // 返回发送数据的消息体
    return_submit_obj(){

    }

    // 更新databinding
    update(){
        /*
            更新databinding
            已有信息：xpath, max_xpath, sub_list
            要更新的信息：sub_list在html的数目，重置预览
        */
        
        $("#span_sub_num").text(this.sub_xpath_binding_list.length);
       
        if (this.is_preview == true){
            this.m_deactive_preview();
            this.m_active_preview();
        }
    }

    // 转换颜色
    showRGB2(code){
        // var a=document.getElementsByName("rgb2")[0].value;
        // if(a.substr(0,1)=="#")a=a.substring(1);
        // var len=a.length;
        // if(len!=6&&len!=3)return alert("十六进制颜色码为六位或三位！");
        // else if(/[^0-9a-f]/i.test(a))return alert("请输入正确的十六进制颜色码！");
        // document.getElementById("color2").bgColor="#"+a;
        let a = code.toLowerCase();
        let b = new Array();
        let result = new Object();
        let len = a.length;
        for(let x = 0; x < 3; x++){
            b[0]=len==6?a.substr(x*2,2):a.substr(x*1,1)+a.substr(x*1,1);
            b[3]="0123456789abcdef";
            b[1]=b[0].substr(0,1);
            b[2]=b[0].substr(1,1);
            b[20+x]=b[3].indexOf(b[1])*16+b[3].indexOf(b[2])
        }
        // a_mo3.innerHTML=b[20]+","+b[21]+","+b[22];
        result = {
            'r': b[20],
            'g': b[21],
            'b': b[22]
        }

        return result;
    }

    // 获取所有颜色
    get_color(){
        /*
            :param return: Object
        */

        let return_obj = new Object();
        return_obj = {
            color_data_binding_background: this.color_data_binding_background,
            color_data_binding_border: this.color_data_binding_border,
            color_max_background: this.color_max_background,
            color_max_border: this.color_max_border,
            color_sub_background: this.color_sub_background,
            color_sub_border: this.color_sub_border
        }

        return return_obj;
    }

    // 获取所有状态
    get_status(){
        /*
            :param return: Object
        */

        let return_obj = new Object();
        return_obj = {
            data_binding_background: $("#cbox_data_binding_background").prop("checked"),
            data_binding_border: $("#cbox_data_binding_border").prop("checked"),
            max_background: $("#cbox_max_background").prop("checked"),
            max_border: $("#cbox_max_bording").prop("checked"),
            sub_background: $("#cbox_sub_background").prop("checked"),
            sub_border: $("#cbox_sub_bording").prop("checked"),
        }

        return return_obj;

    }

    /*
    ===============
    消息传输 to content.js
    "m_" - 消息传输函数
    ===============
    */
    // 发送消息, 显示预览元素
    m_active_preview(){
        console.log("发送数据标定请求");
        // 检查数据标定
        if (this.is_data_binding_done === false){
            web_info_object.display_warning("数据标定未完成");
            return false;
        }

        let send_obj = new Object();
        send_obj.xpath_binding = this.xpath_binding;
        send_obj.max_xpath_binding = this.max_xpath_binding;
        send_obj.sub_xpath_binding_list = this.sub_xpath_binding_list;

        let colors = this.get_color();
        let status = this.get_status();

        let msg = {
            tabId: chrome.devtools.inspectedWindow.tabId,
            todo: "activeBindingDataPreview",
            msg_type: MSG_NORMAL,
            data_binding_set: send_obj,
            colors: colors,
            status: status
        }

        cbf_msg_send_to_background(msg);
    }

    // 隐藏预览元素
    m_deactive_preview(){
        let msg = {
            tabId: chrome.devtools.inspectedWindow.tabId,
            msg_type: MSG_NORMAL,
            todo: "deactiveBindingDataPreview",
        }

        cbf_msg_send_to_background(msg);
        return true;
    }

    // 调整数据绑定位置
    m_adjust_binding_xpath_up(s_xpath, s_max_range_xpath, is_lock_max=-1){
        let msg = this.m_normal_obj;
        msg.todo = "adjust_binding_xpath_up";
        msg.xpath = s_xpath;
        msg.max_range_xpath = s_max_range_xpath;
        msg.is_lock_max = is_lock_max;
        // msg.lock_max = lock_max;

        cbf_msg_send_to_background(msg);
        return true;
    }

    m_adjust_binding_xpath_down(s_xpath, s_xpath_ori, s_max_range_xpath){
        let msg = this.m_normal_obj;
        msg.todo = "adjust_binding_xpath_down";
        msg.xpath = s_xpath;
        msg.xpath_ori = s_xpath_ori;
        msg.max_range_xpath = s_max_range_xpath;

        cbf_msg_send_to_background(msg);
        return true;
    }

    // 调整最大范围
    m_adjust_max_range_up(s_xpath, s_max_range_xpath){
        let msg = this.m_normal_obj;
        msg.todo = "adjust_max_xpath_up";
        msg.max_range_xpath = s_max_range_xpath;
        msg.xpath = s_xpath;

        cbf_msg_send_to_background(msg);
        return true;
    }

    m_adjust_max_range_down(s_xpath, s_max_range_xpath){
        let msg = this.m_normal_obj;
        msg.todo = "adjust_max_xpath_down";
        msg.max_range_xpath = s_max_range_xpath;
        msg.xpath = s_xpath;

        cbf_msg_send_to_background(msg);
        return true;
    }

    /*
        获取数据标定
        指定数据位置,生成最大范围以及子结构
    */
    m_get_data_binding(todo_type, is_lock_max = -1, lock_max = null){
        let msg = this.m_normal_obj;
        msg.todo = "getDataBindingXpath";


        if (mc_BasicInfo.data_acquisition_method === GlobalValue.DATA_METHOD_STRUCTURE){
            msg.todo_type = GlobalValue.XPATH_TYPE_STRUCTURE_GET_DATA_BINDING;
        }else{
            msg.todo_type = todo_type;
        }
        msg.is_lock_max = is_lock_max;
        msg.lock_max = lock_max;
        
        cbf_msg_send_to_background(msg);
        return true;
    }

    // 手动指定最大范围, 最终返回max xpath
    m_get_max_range_xpath(s_xpath){
        let msg = this.m_normal_obj;
        msg.todo = "getMaxRange";
        msg.xpath = s_xpath;

        cbf_msg_send_to_background(msg);
        return true;
    }

    /*
        根据现有的数据(数据位置, 最大范围)生成子结构
    */
    m_get_sub_with_selected_data(){

        // 校验数据
        let data_binding_xpath = this.xpath_binding;
        let data_binding_max = this.max_xpath_binding;

        if (data_binding_xpath === null || data_binding_xpath === undefined || data_binding_max === null || data_binding_max === undefined){
            web_info_object.display_warning("数据标定未完成");
            return false;
        }

        let msg = this.m_normal_obj;
        msg.todo = "getSubWithSelectedData";
        msg.xpath = data_binding_xpath;
        msg.max_range_xpath = data_binding_max;

        cbf_msg_send_to_background(msg);
        return true;
    }

    /*
        翻页按钮
    */
    m_get_turn_page_btn(){
        let send_obj = new Object();

        let msg = {
            tabId: chrome.devtools.inspectedWindow.tabId,
            todo: "get_turn_page_button",
            msg_type: MSG_NORMAL,
            data_binding_set: send_obj
        }

        cbf_msg_send_to_background(msg);
    }

    // 刷新预览
    m_refresh_preview(todo_type, color){
        /*
            :param todo_type:
            - data_binding_background
            - data_binding_border
            - max_background
            - max_border
            - sub_background
            - sub_border

            :param color: Object{r, g, b}
        */

        let msg = Message.get_normal_msg();
        msg.todo = "refresh_preview";
        msg.todo_type = todo_type;
        msg.color = color;
        Message.msg_send_to_background(msg);
    }

    m_update_preview_info(todo_type, status){
        /*
            :param todo_type:
            - data_binding_background
            - data_binding_border
            - max_background
            - max_border
            - sub_background
            - sub_border

            :param status:
            - activate
            - deactivate
        */

        let msg = Message.get_normal_msg();
        msg.todo = "update_preview_info";
        msg.todo_type = todo_type;
        msg.status = status;
        Message.msg_send_to_background(msg);
    }
}

/*
=================
任务本身
=================
*/
class WebInfo{

    /*
        - 单例
        1. 记录全局状态量
        2. 调整项目状态(重置等)
        3. 打包/解压项目数据
    */

    static DATA_METHOD_STRUCTURE = 100;
    static DATA_METHOD_CONTINUE = 101;
    static DATA_METHOD_SIMPLE_LIST = 102;

    // 构造函数
    constructor(){
        this.basic_info = mc_BasicInfo;
        this.get_data = mc_GetData;

    }

    // 初始化项目
    init_web_info(){
    }

    // 返回要提交的数据信息
    // 需要修改
    return_submit_obj(){
        console.log("==return_submit_obj==");

        let return_obj = new Object();
        let basic_info_obj = null;
        let get_data_obj = null;

        basic_info_obj = this.basic_info.return_submit_obj();
        get_data_obj = this.get_data.return_submit_obj();
        if (get_data_obj === false){
            // this.get_data.warning_confirm.display_warning("获取数据部分未完成");
            return false;
        }

        return_obj.basic_info_obj = basic_info_obj;
        return_obj.get_data_obj = get_data_obj;
        return return_obj;
    }

    // 发送数据到background.js
    send_msg_to_background(msg){
        cbf_msg_send_to_background(msg);
    }
}

class UtilityForPanel{
    /*
        工具类

        1. 元素的表现
    */

    /*
        在当前位置,平滑移动到element
        param element:      HtmlElement
        param speed:        int
    */
    animateScroll(element, speed) {

        const UP = 1;
        const DOWN = -1;

        // let rect=element.getBoundingClientRect();
        let current_scrollTop = document.documentElement.scrollTop;
        let element_scrollTop = element.offset().top;
        let direction = UP;
        let requestId;

        // 判断移动方向
        if (current_scrollTop > element_scrollTop){
            // 向上移动
            direction = UP;
        }else{
            // 向下移动
            direction = DOWN;
        }

        //采用requestAnimationFrame，平滑动画
        function step(timestamp) {

            if (direction === UP){
                current_scrollTop -= speed;
                if (current_scrollTop >= element_scrollTop){
                    window.scrollTo(0, current_scrollTop);
                    requestId=window.requestAnimationFrame(step);
                }else{
                    window.cancelAnimationFrame(requestId);
                }
            }else{
                current_scrollTop += speed;
                if (current_scrollTop <= element_scrollTop){
                    window.scrollTo(0, current_scrollTop);
                    requestId=window.requestAnimationFrame(step);
                }else{
                    window.cancelAnimationFrame(requestId);
                }
            }
        }
        window.requestAnimationFrame(step);
    }
}



/*
=================
警告框
=================
*/
class WarningConfirmBar{

    static is_registered = false;

    constructor(){}

    register_warning(){
        
        if (WarningConfirmBar.is_registered === false){

            WarningConfirmBar.is_registered = true;

            let tmp_this = this;

            $("#div_warning_collapse").on("hidden.bs.collapse", function(){
                $(GlobalValue.id_containerWarningConfirm).addClass("d-none");
                // $("#division_for_div_warning").addClass("d-none");
            });
        
            $("#div_warning_collapse").on("shown.bs.collapse", function(){
                utility_for_panel.animateScroll($("#div_warning_collapse"), 10);
            });

            $("#btn_warning_close").click(function(){
                // hide_warning();
                tmp_this.hide_warning();
            });

            this.hide_warning();
        }
    }

    hide_warning(){
        $("#div_warning_collapse").collapse("hide");
        $("#warning_content").text("");
    }

    display_warning(info){
        $(GlobalValue.id_containerWarningConfirm).removeClass("d-none");
        $(GlobalValue.id_divWarningContent).text(info);
        $(GlobalValue.id_divWarningDivision).css("display", "block");
        $(GlobalValue.id_divWarningCollapse).collapse("show");
    }
}

class SubmitConfirmBar{
    constructor(){}

    register_submit_confirm(){
        this.hide_submit_confirm();
    }

    display_submit_confirm(){
        $(GlobalValue.id_containerSubmitConfirm).removeClass("d-none");
        $("#div_submit_confirm").collapse("show");
    }

    hide_submit_confirm(){
        $(GlobalValue.id_containerSubmitConfirm).addClass("d-none");
        $("#div_submit_confirm").collapse("hide");
    }

}


/*
=================
导航栏
=================
*/
class Navigation{
    /*
        导航栏对象
        1. 控制切换时,html元素的表现
        2. 注册导航栏切换监听事件
    */
    constructor(){

    }

    /*
    ==========
    元素表现
    ==========
    */

    reset_nav(div_name){
        /*
            重置导航栏
        */

        // 基本信息
        if ($("#container_basic_info").hasClass("d-none") === false){
            $("#container_basic_info").addClass("d-none");
        }        
    
        // 获取数据
        mc_GetData.hide_get_data();
    
        // 导入项目
        if ($("#container_import_proj").hasClass("d-none") === false){
            $("#container_import_proj").addClass("d-none");
        }

        // 发送数据
        mc_SendData.hide_send_data();

    }

    active_tab(div_name){
        /*
            设置激活的导航栏tab
        */

        $("#a_basic_info").removeClass("active");
        $("#a_get_data").removeClass("active");
        $("#a_import_proj").removeClass("active");
        $("#a_send_data").removeClass("active");
    
    
        if (div_name === "basic_info"){
            $("#a_basic_info").addClass("active");
        }else if(div_name === "get_data"){
            $("#a_get_data").addClass("active");
        }else if(div_name === "import_proj"){
            $("#a_import_proj").addClass("active");
        }else if(div_name === "send_data"){
            $("#a_send_data").addClass("active");
        }
    
    }
    
    display_basic_info(){
        this.active_tab("basic_info");
        mc_BasicInfo.display_basic_info();
    }

    display_get_data(){
        this.active_tab("get_data");
        mc_GetData.display_get_data_factory(mc_BasicInfo.data_acquisition_method);
    }

    display_import_proj(){
        this.active_tab("import_proj");
    }

    display_send_data(){
        this.active_tab("send_data");
        mc_SendData.display_send_data();
        
    }

    register_all_listener(){
        // 注册所有元素的监听事件
        mc_GetData.register_GetData();
        mc_BasicInfo.register_BasicInfo();
        mc_SendData.register_SendData();
        // this.register_BasicInfo();
    }
}

/*
=================
基本信息
=================
*/
class BasicInfo{
    constructor(){
        this.project_name = "Project name";                             // 项目名称
        this.project_intro = "Project Introduction";                    // 项目简介
        this.server_url = "http://localhost:8000/";                     // 服务器地址
        this.current_url = "";                                          // 当前(目标网页)地址
        this.cookies = null;                                            // 目标网页的cookie信息
        this.cookes_length = 0;                                         // cookies长度
        this.data_acquisition_method = WebInfo.DATA_METHOD_SIMPLE_LIST;   // 数据获取方式
    }

    register_BasicInfo(){
        let mc_this = this;

        $("#a_basic_info").click(function(){
            console.log("==get basic info==");
            mc_Navigation.reset_nav("basic_info");
            mc_Navigation.display_basic_info();
    
            // 填充表单选项
            $("#project_name").val(mc_this.project_name);
            $("#project_intro").val(mc_this.project_intro);
            $("#backend_address").val(mc_this.server_url);
            if (mc_this.data_acquisition_method === WebInfo.DATA_METHOD_STRUCTURE){
                $("#data_acquisition_method")[0].options[0].selected = true
            }else if(mc_this.data_acquisition_method === WebInfo.DATA_METHOD_CONTINUE){
                $("#data_acquisition_method")[0].options[1].selected = true
            }else if(mc_this.data_acquisition_method === WebInfo.DATA_METHOD_SIMPLE_LIST){
                $("#data_acquisition_method")[0].options[2].selected = true
            }
    
            // 获取网页地址以及cookies
            let msg = {
                tabId: chrome.devtools.inspectedWindow.tabId,
                todo: "getBasicInfo"
            }
            // get_basic_info(msg);
            // cbf_msg_send_to_background(msg);
            web_info_object.send_msg_to_background(msg);
        });


        $(GlobalValue.id_valueProjectName).change(function(){
            mc_this.project_name = $(this).val();
        });
    
        $(GlobalValue.id_valueProjectIntroduction).change(function(){
            mc_this.project_intro = $(this).val();
        });
    
        $(GlobalValue.id_valueBackendAddress).change(function(){
            mc_this.server_url = $(this).val();
        });
    
        $(GlobalValue.id_valueAcquisitionMethod).change(function(){
            if ($(this)[0].value === "data_acquisition_method_structure"){
                mc_this.data_acquisition_method = GlobalValue.DATA_METHOD_STRUCTURE;
            }else if($(this)[0].value === "data_acquisition_method_continues"){
                mc_this.data_acquisition_method = GlobalValue.DATA_METHOD_CONTINUE;
            }else if($(this)[0].value === "data_acquisition_method_simple_list"){
                mc_this.data_acquisition_method = GlobalValue.DATA_METHOD_SIMPLE_LIST;
            }
        });
    }

    display_basic_info(){
        $(GlobalValue.id_containerBasicInfo).removeClass("d-none");
    }

    return_submit_obj(){
        let return_obj = new Object();
        return_obj.project_name = this.project_name;
        return_obj.project_intro = this.project_intro;
        return_obj.server_url = this.server_url;
        return_obj.current_url = this.current_url;
        return_obj.cookies = this.cookies;
        return_obj.cookies_length = this.cookies.length;
        return_obj.data_acquisition_method = this.data_acquisition_method;
        return return_obj;
    }
}


/*
=================
获取数据
=================
*/
class GetData{
    constructor(){
        this.warning_confirm = new WarningConfirmBar();
        this.submit_confirm = new SubmitConfirmBar();

        this.simple_list = new GetDataSimpleList();
        this.structure = new GetDataStructure();
        this.continues = new GetDataContinues();
    }

    register_GetData(){
        // 注册整个获取数据页面
        $("#a_get_data").click(function(){
            // Navigation.reset_nav("get_data");
            mc_Navigation.reset_nav();
            mc_Navigation.display_get_data();
    
            if (web_info_object.basic_info.data_acquisition_method === GlobalValue.DATA_METHOD_SIMPLE_LIST){
                mc_GetData.simple_list.active_GetDataSimpleList();
            }else if(web_info_object.basic_info.data_acquisition_method === GlobalValue.DATA_METHOD_STRUCTURE){
                mc_GetData.structure.active_GetDataStructure();
            }else if(web_info_object.basic_info.data_acquisition_method === GlobalValue.DATA_METHOD_CONTINUE){
                mc_GetData.continues.active_GetDataContinues();
            }else{
                console.log("==register_GetData==");
                console.log("Error: data acquisition method match error");
                console.log("web_info_object.data_acquisition_method:" + web_info_object.data_acquisition_method);
            }
        });

        this.simple_list.register_GetDataSimpleList();
        this.structure.register_GetDataStructure();
        this.continues.register_GetDataContinues();
        // GetDataContinues.register_GetDataContinues();
        // GetDataStructure.register_GetDataStructure();

        this.warning_confirm.register_warning();
        this.submit_confirm.register_submit_confirm();        
    }

    hide_get_data(){
        // 隐藏获取数据页面
        $(GlobalValue.id_containerGetData).addClass("d-none");
        $(GlobalValue.id_containerDatabinding).addClass("d-none");
        $(GlobalValue.id_containerGetDataSimpleList).addClass("d-none");
        $(GlobalValue.id_containerGetDataContinues).addClass("d-none");
        $(GlobalValue.id_containerGetDataStructure).addClass("d-none");
    }

    display_get_data_factory(data_acquisition_method){
        /*
            数据页面显示策略工厂
            :param data_acquisition_method: GlobalValue.DATA_METHOD_*
        */

        $(GlobalValue.id_containerGetData).removeClass("d-none");

        if (data_acquisition_method === GlobalValue.DATA_METHOD_SIMPLE_LIST){
            this.display_GetDataSimpleList();
        }else if (data_acquisition_method === GlobalValue.DATA_METHOD_CONTINUE){
            this.display_GetDataContinues();
        }else if (data_acquisition_method === GlobalValue.DATA_METHOD_STRUCTURE){
            this.display_GetDataStructure();
        }else{
            console.log("==show_get_data_factory==");
            console.log("Error: can not find the match data acquisition method");
            console.log("data_acquisition_method:" + data_acquisition_method);
            return false;
        }
    }

    display_GetDataSimpleList(){
        $(GlobalValue.id_containerDatabinding).removeClass("d-none");
        $(GlobalValue.id_containerGetDataSimpleList).removeClass("d-none");
        this.simple_list.data_binding_set.update_html();
    }

    display_GetDataContinues(){
        // $(GlobalValue.id_containerDatabinding).removeClass("d-none");
        $(GlobalValue.id_containerGetDataContinues).removeClass("d-none");
    }

    display_GetDataStructure(){
        $(GlobalValue.id_containerDatabinding).removeClass("d-none");
        $(GlobalValue.id_containerGetDataStructure).removeClass("d-none");
        this.simple_list.data_set.deactive_all_preview();
        this.structure.data_binding_set.update_html();
    }

    return_submit_obj(){
        let return_obj = null;
        let data_acquisition_method = web_info_object.basic_info.data_acquisition_method;

        if (data_acquisition_method === WebInfo.DATA_METHOD_SIMPLE_LIST){
            return_obj = this.simple_list.return_submit_obj();
        }else if(data_acquisition_method === WebInfo.DATA_METHOD_STRUCTURE){
            return_obj = this.structure.return_submit_obj();
        }else if(data_acquisition_method === WebInfo.DATA_METHOD_CONTINUE){

        }

        return return_obj;
    }
}

class GetDataSimpleList{
    constructor(){
        // 数据获取
		this.data_binding_set = new DataBinding();                      // 数据标定
        this.data_set = new DatasetObj(this.data_binding_set);			// 数据组
    }

    register_GetDataSimpleList(){
        /*
            注册简单列表
        */

        // 默认添加一个数据组
        let first_data_set = new DataSet();
        first_data_set.deactive_preview();
        this.data_set.data_set_list.insert_element(first_data_set);
        this.data_set.current_active_data_set = 0;        

        /*
        =================
        数据标定的按钮事件监听
        =================
        */
           
        this.data_binding_set.register();


        /*
        =================
        数据组控制栏的按钮监听事件
        =================
        */

        /*
        动态添加的按钮, 在动态添加之后再绑定数据, 具体位置: bind_btn_operation_bar()
        */

        this.data_set.register();
    }

    active_GetDataSimpleList(){
        /*
            激活简单列表 - 显示元素
        */

        this.data_binding_set.active();
        this.data_set.active();
    }

    return_submit_obj(){
        let return_obj = new Object();

        if (this.data_binding_set.is_data_binding_done() === true){
            // 数据标定信息
            return_obj.data_binding_main = this.data_binding_set.xpath_binding;
            return_obj.data_binding_max = this.data_binding_set.max_xpath_binding;
            return_obj.data_binding_sub_list = this.data_binding_set.sub_xpath_binding_list_to_obj();
            return_obj.data_binding_sub_list_length = this.data_binding_set.sub_xpath_binding_list.length;

            // 目标数据
            // 写一个 data_set list 2 obj 的转换函数
            return_obj.data_set_list = this.data_set.data_set_list_to_obj(this.data_set.data_set_list);
            return_obj.data_set_list_length = this.data_set.data_set_list.list_length;
            return return_obj;
        }else {
            return false;
        }  
    }
}
